﻿Imports System.IO
Imports System.Security.Cryptography
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.Web.Security
Imports System.Net
Imports System.Xml
Imports BigfootSQL
Imports System.Text
Imports System.Web
Imports System.Collections.Specialized


Namespace AboutDNN.DNNMVC

    Public Class App

        ' Name of the folder where the module resides
        Public Const ModuleFolderName As String = "AboutDNN_Flash3DImageSlider"
        ' The database object qualifier
        Public Const ModuleDBObjectQualifier As String = "Mitmar_TimeMaster"
        ' The root namespace of the modlue (where the controllers, etc. are)
        Public Const ModuleNamespace As String = "M2Land.Modules.Flash3DImageSlider"

        Public Const AppPath As String = "~/desktopmodules/" & App.ModuleFolderName & "/"
        Public Const ViewsPath As String = AppPath & "Views/"
        Public Const ImagesPath As String = AppPath & "content/images/"
        Public Const JSPath As String = AppPath & "content/js/"
        Public Const CSSPath As String = AppPath & "content/css/"
        Public Const DBPath As String = AppPath & "content/db/"
        Public Const FlashPath As String = AppPath & "content/flash/"
        Public Const XMLPath As String = AppPath & "content/xml/"
        Public Const ErrorViewPath As String = AppPath & "error.ascx"


        ''' <summary>
        ''' Delegate called before the MVC framework is initialized. Use this to set the configration settings for the app
        ''' </summary>
        Delegate Function App_PreInit()

        ''' <summary>
        ''' Delegate called when the application after the MVC framework is initializeed
        ''' </summary>
        Delegate Function App_Init()

        ''' <summary>
        ''' Deletegate called on every reqeust executed by MVC
        ''' </summary>
        Delegate Function Request_Init()


        ''' <summary>
        ''' Delegate called before the MVC framework is initialized. Use this to set the configration settings for the app
        ''' </summary>
        Public Shared PreInitCallback As App_PreInit

        ''' <summary>
        ''' Delegate called when the application after the MVC framework is initializeed
        ''' </summary>
        Public Shared InitCallback As App_Init

        ''' <summary>
        ''' Deletegate called on every reqeust executed by MVC
        ''' </summary>
        Public Shared RequestCallback As Request_Init


#Region "InitMVC"
        Private Shared _BigfootMVCInitialized = False

        ' THIS METHOD SHOULD BE CALLED ON EVERY REQUEST BY THE ROUTE PAGE AND ROUTE CONTROL
        Public Shared Sub InitMVC()

            ' Initialized the application
            If _BigfootMVCInitialized = False Then

                ' Call the pre_init
                If PreInitCallback IsNot Nothing Then PreInitCallback.Invoke()

                ' Mark the MVC portion as initialized
                _BigfootMVCInitialized = True

                ' Call the application_init function
                If InitCallback IsNot Nothing Then InitCallback.Invoke()

            End If

            ' Perform Request Level Init


            ' Call the Request_Init function
            If RequestCallback IsNot Nothing Then RequestCallback.Invoke()

        End Sub


#End Region



#Region "Context"

        ' When the set to nothing, it removes the manual context, and returns the system to it's default state
        Public Shared Sub OverrideMVCContext(ByVal newContext As RequestContext)
            If newContext Is Nothing Then
                App.Cache.Remove(Params.Cache.ManualContext)
            Else
                App.Cache.Add(Params.Cache.ManualContext, newContext)
            End If
        End Sub

        Public Shared Function MVCContext() As RequestContext
            ' Check weather a manual override was done for the context
            If App.Cache.Contains(Params.Cache.ManualContext) Then
                Return App.Cache.GetValue(Params.Cache.ManualContext)
            End If

            ' If the context is empty, instance it up
            If HttpContext.Current.Items(Params.Cache.RequestContext) Is Nothing Then
                HttpContext.Current.Items(Params.Cache.RequestContext) = New RequestContext
            End If
            Return HttpContext.Current.Items(Params.Cache.RequestContext)
        End Function

#End Region


#Region "DB"

        Public Shared Function DB() As DataProvider
            Return MVCContext.DB
        End Function


#End Region


#Region "Client URL"

        ''' <summary>
        ''' Retreives the the path to a file that can be used by the browser
        ''' </summary>
        ''' <param name="fileName">the name of the file including the extension</param>
        Public Shared Function ClientUrl(ByVal filename As String) As String
            Return App.MVCContext.DNN.GetClientUrl(FileRelativeUrl(filename))
        End Function

        ''' <summary>
        ''' Creates the client url needed 
        ''' </summary>
        Public Shared Function ClientUrl(ByVal controller As String, ByVal action As String) As String
            Return ClientUrl(controller, action, String.Empty)
        End Function

        ''' <summary>
        ''' Creates the client url needed 
        ''' </summary>
        Public Shared Function ClientUrl(ByVal controller As String, ByVal action As String, ByVal querystring As String) As String
            Return ClientUrl(controller, action, querystring, False)
        End Function

        Public Shared Function ClientUrl(ByVal controller As String, ByVal action As String, ByVal querystring As String, ByVal fullUrl As Boolean) As String
            Dim relurl = MVCContext.DNN.CreateUrl(BuildUrlQS(controller, action, querystring).ToArray)
            If fullUrl AndAlso relurl.StartsWith("http") = False Then
                relurl = MakeUrlAbsolute(relurl, True)
            End If
            Return relurl
        End Function

        Public Shared Function ClientUrlForAjax(ByVal controller As String, ByVal action As String) As String
            Return ClientUrlForAjax(controller, action, String.Empty)
        End Function

        Public Shared Function ClientUrlForAjax(ByVal controller As String, ByVal action As String, ByVal querystring As String) As String
            Dim relurl = App.AppPath & "route.ashx?" & BuildUrlQSAsString(controller, action, querystring)
            If relurl.StartsWith("~/") Then relurl = relurl.Substring(2)
            If relurl.EndsWith("/") Then relurl = relurl.Substring(0, relurl.Length - 1)
            Return App.MVCContext.ApplicationPath & "/" & relurl
        End Function

        ''' <summary>
        ''' Returns the relative file path of a file based on it's extentsion
        ''' </summary>
        ''' <param name="fileName">the name of the file including the extension</param>
        Public Shared Function FileRelativeUrl(ByVal fileName As String) As String
            fileName = fileName.ToLower
            If fileName.EndsWith("js") Then
                Return JSPath & fileName
            ElseIf fileName.EndsWith("css") Then
                Return CSSPath & fileName
            ElseIf fileName.EndsWith("jpg") Or _
                   fileName.EndsWith("gif") Or _
                   fileName.EndsWith("png") Then
                Return ImagesPath & fileName
            ElseIf fileName.EndsWith("sql") Then
                Return DBPath & fileName
            ElseIf fileName.EndsWith("xml") Then
                Return XMLPath & fileName
            ElseIf fileName.EndsWith("swf") Then
                Return FlashPath & fileName
            Else
                Return fileName
            End If
        End Function

        Public Shared Function FilePhysicalPath(ByVal fileName As String) As String
            Return MVCContext.MapPath(FileRelativeUrl(fileName))
        End Function

        Public Shared Function DirectoryPhysicalPath(ByVal relativePath As String) As String
            Return MVCContext.MapPath(relativePath)
        End Function

        Public Shared Function LoginUrl() As String
            Dim url = FormsAuthentication.LoginUrl()
            If url.Contains("?") = False Then
                url += "?"
            Else
                url += "&"
            End If
            url += "returnurl=" & HttpUtility.UrlEncode(ClientUrl("Home", "Default"))
            Return url
        End Function

        Public Shared Function ApplicationPath() As String
            Dim apppath = MVCContext.Request.ApplicationPath
            If apppath.EndsWith("/") = False Then apppath = apppath & "/"
            Return apppath
        End Function

        Public Shared Function ApplicationHost() As String
            Dim port As String = MVCContext.Request.ServerVariables("SERVER_PORT")
            If String.IsNullOrEmpty(port) OrElse port = "80" OrElse port = "443" Then
                port = ""
            Else
                port = ":" & port
            End If
            Dim protocol As String = HttpContext.Current.Request.ServerVariables("SERVER_PORT_SECURE")
            If String.IsNullOrEmpty(protocol) OrElse protocol = "0" Then
                protocol = "http://"
            Else
                protocol = "https://"
            End If
            Dim domain = MVCContext.Request.ServerVariables("SERVER_NAME")
            Return protocol & domain & port & "/"
        End Function

        Public Shared Function FullApplicationPath() As String
            Dim value = ApplicationHost()
            ' Add the application path only when the app is not at the root of the domain
            If ApplicationPath() <> "/" Then
                If ApplicationPath.StartsWith("/") Then
                    value += ApplicationPath.Substring(1)
                Else
                    value += ApplicationPath()
                End If
            End If
            Return value
        End Function

        Public Shared Function MakeUrlAbsolute(ByVal url As String, ByVal fullpath As Boolean) As String
            Dim apppath = IIf(fullpath, ApplicationPath, _
                                        FullApplicationPath)
            If url.StartsWith("~/") Then
                url = url.Substring(2)
            End If
            If url.StartsWith("/") Then url = url.Substring(1)
            Return apppath & url
        End Function

        Private Shared Function BuildUrlQS(ByVal controller As String, ByVal action As String) As List(Of String)
            Return BuildUrlQS(controller, action, Nothing)
        End Function

        Private Shared Function BuildUrlQSAsString(ByVal controller As String, ByVal action As String, ByVal querystring As String) As String
            Dim qs = BuildUrlQS(controller, action, querystring)
            Dim qstring As String = ""
            For Each s As String In qs.ToArray
                If qstring.Length > 0 Then qstring += "&"
                qstring += s
            Next
            Return qstring
        End Function

        Private Shared Function BuildUrlQS(ByVal controller As String, ByVal action As String, ByVal querystring As String) As List(Of String)
            Dim qs = New List(Of String)
            Dim paramFormat = "{0}={1}"
            qs.Add(String.Format(paramFormat, Params.Controller, controller))
            qs.Add(String.Format(paramFormat, Params.Action, action))
            qs.Add(String.Format(paramFormat, Params.TabId, MVCContext.DNN.TabID))
            qs.Add(String.Format(paramFormat, Params.PortalId, MVCContext.DNN.PortalID))

            If String.IsNullOrEmpty(querystring) = False Then
                For Each s As String In querystring.Split("&")
                    Dim qsItem = s.Split("=")
                    If qsItem.Length > 1 Then
                        qs.Add(String.Format(paramFormat, qsItem(0), qsItem(1)))
                    Else
                        qs.Add(String.Format(paramFormat, s, ""))
                    End If

                Next
            End If
            Return qs
        End Function

#End Region


#Region "PortalID / UserID"

        Public Shared ReadOnly Property PortalID() As Integer
            Get
                Try
                    Return MVCContext.DNN.PortalID
                Catch ex As Exception
                    App.HandleException(ex)
                End Try
            End Get
        End Property

        Public Shared ReadOnly Property UserID() As Integer
            Get
                Try
                    Return MVCContext.DNN.UserID
                Catch ex As Exception
                    App.HandleException(ex)
                End Try
            End Get
        End Property

#End Region


#Region "HandleException"
        Public Shared Sub HandleException(ByVal ex As Exception)
            HandleException(ex, True)
        End Sub

        ''' <summary>
        ''' Handles an exception
        ''' </summary>
        ''' <param name="ex">The exception to be handled</param>
        Public Shared Sub HandleException(ByVal ex As Exception, ByVal ReThrow As Boolean)

            ' Ignore exceptions due to response manually ended
            If MVCContext.Response.EndCalled Then
                Exit Sub
            End If

            ' Log the exception in DNN
            MVCContext.DNN.LogException(ex)

            ' When an ajax request, signal to the client that the request failed.
            If IsAjaxRequest() Then
                MVCContext.Response.Clear()

                MVCContext.Response.Write(RouteHelper.RenderPartial("shared", "error", ErrorViewModel.Create(ex)))

                ' Set the status code to 402 for security problems
                If (ex.GetType.Name = GetType(System.Security.SecurityException).Name) OrElse _
                        (ex.InnerException IsNot Nothing AndAlso _
                         ex.InnerException.GetType.Name Is GetType(System.Security.SecurityException).Name) Then
                    MVCContext.Response.StatusCode = 402
                Else
                    MVCContext.Response.StatusCode = 500
                End If

                MVCContext.Response.StatusDescription = ex.Message
                MVCContext.Response.End()
            ElseIf ReThrow Then
                Throw ex
            End If
        End Sub

#End Region


#Region "DataFolder / GetFilePath / CreateFilePath"

        Public Shared Function DataFolder() As String
            If App.Cache.Contains(Params.Cache.DataFolder(App.PortalID)) = False Then
                Dim dirPath As String = MVCContext.DNN.PortalPath & "\" & ModuleFolderName & "\"
                ' Create if not found
                If Directory.Exists(dirPath) = False Then
                    Directory.CreateDirectory(dirPath)
                End If
                App.Cache.Add(Params.Cache.DataFolder(App.PortalID), dirPath)
            End If

            Return App.Cache.GetValue(Params.Cache.DataFolder(App.PortalID))
        End Function

        ' Creates a valid file path and name and returns it
        '   Returns: The file path and name e.g. c:\inetpub\wwwroot\portals\0\modulename\file1.xls
        Public Shared Function CreateFilePath(ByVal FileName As String) As String
            Dim name As String = Path.GetFileNameWithoutExtension(FileName)
            Dim ext As String = Path.GetExtension(FileName)

            ' Add the dot to the ext
            ext = IIf(String.IsNullOrEmpty(ext), "", "." & ext)

            ' Clean up the file name
            For Each c In Path.GetInvalidFileNameChars
                name = name.Replace(c, "_")
            Next

            ' Get a unique filename
            Dim nameCount As Integer = 0
            Do While File.Exists(DataFolder() & name & ext)
                name += nameCount
                nameCount += 1
            Loop

            ' Return the full file name
            Return DataFolder() & name & ext
        End Function

        ' Gets the path used a file name and note
        '   Returns: The file path and name e.g. c:\inetpub\wwwroot\portals\0\modulename\file1.xls</returns>
        Public Shared Function GetFilePath(ByVal FileName As String) As String
            Return DataFolder() & FileName
        End Function

#End Region


#Region "FillFromRequest"
        Public Shared Function FillFromRequest(Of T)() As T
            Return FillFromRequest(Of T)("")
        End Function

        Public Shared Function FillFromRequest(Of T)(ByVal prefix As String) As T
            Return SqlHelper.FillObject(Of T)(MVCContext.RequestValues, prefix)
        End Function

        Public Shared Sub FillFromRequest(ByVal objectToFill As Object)
            FillFromRequest(objectToFill, "")
        End Sub

        Public Shared Sub FillFromRequest(ByVal objectToFill As Object, ByVal prefix As String)
            SqlHelper.FillObject(objectToFill, MVCContext.RequestValues, prefix)
        End Sub
#End Region


#Region "REST"
        Public Shared Function RestPost(ByVal url As String, ByVal postData As NameValueCollection) As String
            Dim wc = New WebClient()
            Dim response = wc.UploadValues(url, "POST", postData)
            Return New StreamReader(New MemoryStream(response)).ReadToEnd
        End Function

        Public Shared Function RestPostPostAndReturnXml(ByVal url As String, ByVal postData As NameValueCollection) As XmlDocument
            Dim doc = New XmlDocument
            doc.LoadXml(RestPost(url, postData))
            Return doc
        End Function
#End Region


#Region "IsAjaxRequest / IsInDebugMode"

        ''' <summary>
        ''' Determine if the current request is an ajax request
        ''' </summary>
        Public Shared Function IsAjaxRequest() As Boolean
            Return MVCContext.Headers(Params.HttpHeaders.ajaxRequest) = "true"
        End Function

        Public Shared Function IsInDebugMode() As Boolean
#If DEBUG Then
            Return True
#Else
            Return False
#End If
        End Function

#End Region


#Region "Cache"

        Public Class Cache

            Private Shared _cache As New Dictionary(Of String, Object)

            Private Shared Function GetKey(ByVal key As String) As String
                Return App.ModuleFolderName + ":BigfootMVC:" + key
            End Function

            Public Shared Function Contains(ByVal key As String) As Boolean
                Return _cache.ContainsKey(GetKey(key))
            End Function

            Public Shared Function GetValue(ByVal key As String) As Object
                key = GetKey(key)
                If _cache.ContainsKey(key) Then
                    Return _cache(key)
                Else
                    Return Nothing
                End If
            End Function

            Public Shared Sub Add(ByVal key As String, ByVal data As Object)
                key = GetKey(key)
                If _cache.ContainsKey(key) Then
                    _cache(key) = data
                Else
                    _cache.Add(key, data)
                End If
            End Sub

            Public Shared Sub Remove(ByVal key As String)
                key = GetKey(key)
                If _cache.ContainsKey(key) Then
                    _cache.Remove(key)
                End If
            End Sub

        End Class

#End Region


#Region "Encryption"

        Public Shared Function Encrypt(ByVal strKey As String, ByVal strData As String) As String

            Dim strValue As String = ""

            If strKey <> "" Then
                ' convert key to 16 characters for simplicity
                Select Case Len(strKey)
                    Case Is < 16
                        strKey = strKey & Left("XXXXXXXXXXXXXXXX", 16 - Len(strKey))
                    Case Is > 16
                        strKey = Left(strKey, 16)
                End Select

                ' create encryption keys
                Dim byteKey() As Byte = Encoding.UTF8.GetBytes(Left(strKey, 8))
                Dim byteVector() As Byte = Encoding.UTF8.GetBytes(Right(strKey, 8))

                ' convert data to byte array
                Dim byteData() As Byte = Encoding.UTF8.GetBytes(strData)

                ' encrypt 
                Dim objDES As New DESCryptoServiceProvider
                Dim objMemoryStream As New MemoryStream
                Dim objCryptoStream As New CryptoStream(objMemoryStream, objDES.CreateEncryptor(byteKey, byteVector), CryptoStreamMode.Write)
                objCryptoStream.Write(byteData, 0, byteData.Length)
                objCryptoStream.FlushFinalBlock()

                ' convert to string and Base64 encode
                strValue = Convert.ToBase64String(objMemoryStream.ToArray())
            Else
                strValue = strData
            End If

            Return strValue

        End Function

        Public Shared Function Decrypt(ByVal strKey As String, ByVal strData As String) As String

            Dim strValue As String = ""

            If strKey <> "" Then
                ' convert key to 16 characters for simplicity
                Select Case Len(strKey)
                    Case Is < 16
                        strKey = strKey & Left("XXXXXXXXXXXXXXXX", 16 - Len(strKey))
                    Case Is > 16
                        strKey = Left(strKey, 16)
                End Select

                ' create encryption keys
                Dim byteKey() As Byte = Encoding.UTF8.GetBytes(Left(strKey, 8))
                Dim byteVector() As Byte = Encoding.UTF8.GetBytes(Right(strKey, 8))

                ' convert data to byte array and Base64 decode
                Dim byteData(strData.Length) As Byte
                Try
                    byteData = Convert.FromBase64String(strData)
                Catch ' invalid length
                    strValue = strData
                End Try

                If strValue = "" Then
                    Try
                        ' decrypt
                        Dim objDES As New DESCryptoServiceProvider
                        Dim objMemoryStream As New MemoryStream
                        Dim objCryptoStream As New CryptoStream(objMemoryStream, objDES.CreateDecryptor(byteKey, byteVector), CryptoStreamMode.Write)
                        objCryptoStream.Write(byteData, 0, byteData.Length)
                        objCryptoStream.FlushFinalBlock()

                        ' convert to string
                        Dim objEncoding As System.Text.Encoding = System.Text.Encoding.UTF8
                        strValue = objEncoding.GetString(objMemoryStream.ToArray())
                    Catch ' decryption error
                        strValue = ""
                    End Try
                End If
            Else
                strValue = strData
            End If

            Return strValue

        End Function

#End Region


#Region "Serializer"

        Public Shared Function JsonSerialize(ByVal data As Object) As String
            Return JsonSerialize(data, False)
        End Function

        Public Shared Function JsonSerialize(ByVal data As Object, ByVal ConvertToBase64 As Boolean) As String
            Dim objdata = Newtonsoft.Json.BigfootMVC.JavaScriptConvert.SerializeObject(data)
            If ConvertToBase64 Then
                objdata = ToBase64(objdata)
            End If
            Return objdata
        End Function

        Public Shared Function JsonDeserialize(Of T)(ByVal data As String) As T
            Return JsonDeserialize(Of T)(data, False)
        End Function

        Public Shared Function JsonDeserialize(Of T)(ByVal data As String, ByVal ConvertFromBase64 As Boolean) As T
            If ConvertFromBase64 Then
                data = FromBase64(data)
            End If
            Return Newtonsoft.Json.BigfootMVC.JavaScriptConvert.DeserializeObject(Of T)(data)
        End Function

        Public Shared Function ToBase64(ByVal data As String) As String
            Dim enc = New UTF8Encoding
            Return Convert.ToBase64String(enc.GetBytes(data))
        End Function

        Public Shared Function FromBase64(ByVal data As String) As String
            Dim enc = New UTF8Encoding
            Return enc.GetString(Convert.FromBase64String(data))
        End Function

        Public Shared Function BinSerialize(ByVal data As Object) As String
            Dim ser = New BinaryFormatter()
            Using ms As New MemoryStream
                ser.Serialize(ms, data)
                ms.Flush()
                ms.Position = 0
                Return Convert.ToBase64String(ms.ToArray)
            End Using
        End Function

        Public Shared Function BinDeserialize(Of T)(ByVal base64String As String) As T
            Using ms As New MemoryStream(Convert.FromBase64String(base64String))
                ms.Position = 0
                Dim ser = New BinaryFormatter()
                Return ser.Deserialize(ms)
            End Using
        End Function

#End Region


#Region "GetValue functions"

        Public Shared Function ReplaceToken(ByVal data As String, ByVal token As String, ByVal value As String) As String
            Return data.Replace("||" & token.ToLower & "||", value)
        End Function

        Public Shared Function ReplaceToken(ByVal data As String, ByVal token As String, ByVal value As String, ByVal prefix As String, ByVal suffix As String) As String
            Return data.Replace(prefix & token.ToLower & suffix, value)
        End Function

        Public Shared Function GetValueOrError(ByVal name As String) As String
            Return GetValueOrError(name, False)
        End Function

        Public Shared Function GetValueOrError(ByVal name As String, ByVal decode As Boolean) As String
            Dim value As String
            If String.IsNullOrEmpty(MVCContext.RequestValue(name)) Then
                Throw New ApplicationException("Expected value not found: " & name)
            End If
            value = MVCContext.RequestValue(name)
            If decode Then
                value = HttpUtility.UrlDecode(value)
            End If
            Return value
        End Function

        Public Shared Sub RequireValue(ByVal name As String)
            If String.IsNullOrEmpty(MVCContext.RequestValue(name)) Then
                Throw New ApplicationException("Expected value not found: " & name)
            End If
        End Sub

        Public Shared Function GetValue(ByVal key As String) As String
            Return MVCContext.RequestValue(key)
        End Function

        Public Shared Function GetInt(ByVal key As String) As Integer?
            Dim result = New Integer?
            If MVCContext.RequestValue(key) IsNot Nothing Then
                result = MVCContext.RequestValue(key)
            End If
            Return result
        End Function

        Public Shared Function GetIntArray(ByVal key As String) As List(Of Integer)
            Dim result = New List(Of Integer)
            If MVCContext.RequestValue(key) IsNot Nothing Then
                Dim value = MVCContext.RequestValue(key)
                ' Identify the devider
                Dim devider = ","
                If value.Contains(";") Then
                    devider = ";"
                ElseIf value.Contains("|") Then
                    devider = "|"
                End If
                ' Strip the first and last characters if they are deviders
                If value.StartsWith(devider) Then value = value.Substring(1)
                If value.EndsWith(devider) Then value = value.Substring(0, value.Length - 2)

                ' Split the string and add to the list
                For Each v As Integer In value.Split(devider)
                    result.Add(v)
                Next
            End If
            Return result
        End Function

        Public Shared Function GetDecimal(ByVal key As String) As Decimal?
            Dim result = New Decimal?
            If MVCContext.RequestValue(key) IsNot Nothing Then
                result = MVCContext.RequestValue(key)
            End If
            Return result
        End Function

        Public Shared Function GetDouble(ByVal key As String) As Double?
            Dim result = New Double?
            If MVCContext.RequestValue(key) IsNot Nothing Then
                result = MVCContext.RequestValue(key)
            End If
            Return result
        End Function

        Public Shared Function GetDate(ByVal key As String) As Date?
            Dim result = New Date?
            Dim value As Date
            If MVCContext.RequestValue(key) IsNot Nothing AndAlso Date.TryParse(MVCContext.RequestValue(key), value) Then
                result = value
            End If
            Return result
        End Function

        Public Shared Function GetBool(ByVal key As String) As Boolean
            If MVCContext.RequestValue(key) IsNot Nothing AndAlso _
                    (MVCContext.RequestValue(key).ToLower = "true" Or _
                     MVCContext.RequestValue(key).ToLower = "yes" Or _
                     MVCContext.RequestValue(key).ToLower = "on" Or _
                     MVCContext.RequestValue(key).ToLower = "1") Then
                Return True
            Else
                Return False
            End If
        End Function

#End Region


#Region "Ajax"
        Public Shared Function Ajax(ByVal url As String) As AjaxRequest
            Return AjaxRequest.Create(url)
        End Function

        Public Shared Function Ajax(ByVal url As String, ByVal ParamArray params() As String) As AjaxRequest
            Return AjaxRequest.Create(url, params)
        End Function
#End Region


#Region "JSReferences / CSSReferences"
        Public Shared Function JSReference(ByVal fileName As String) As String
            Return JSReference(fileName, String.Empty)
        End Function

        '<script src="content/js/libraries/01-jquery-1.3.2.debug.js" type="text/javascript"></script>
        Public Shared Function JSReference(ByVal fileName As String, ByVal loadedCheck As String) As String
            If fileName.ToLower.EndsWith(".js") = False Then fileName += ".js"

            If String.IsNullOrEmpty(loadedCheck) Then
                Return New HtmlHelper.TagBuilder("script").src(ClientUrl(fileName)).attr("type", "text/javascript").ToString
            Else
                Return String.Format("<script type='text/javascript'> if (!{0}) loadScript('{1}'); </script>", loadedCheck, ClientUrl(fileName))
            End If
        End Function

        ' <link href="content/css/ModCSS.css" rel="stylesheet" type="text/css" />
        Public Shared Function CSSReference(ByVal fileName As String) As String
            If fileName.ToLower.EndsWith(".css") = False Then fileName += ".css"
            Return New HtmlHelper.TagBuilder("link").href(ClientUrl(fileName)).attr("rel", "stylesheet").attr("type", "text/css").ToString
        End Function
#End Region


    End Class

End Namespace
